package cn.iocoder.yudao.module.def.service.code;

import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNodeConfig;
import cn.hutool.core.lang.tree.TreeUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.stereotype.Service;

import org.springframework.validation.annotation.Validated;

import java.util.*;
import cn.iocoder.yudao.module.def.controller.admin.code.vo.*;
import cn.iocoder.yudao.module.def.dal.dataobject.code.CodeDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;

import cn.iocoder.yudao.module.def.dal.mysql.code.CodeMapper;

import javax.annotation.Resource;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.def.enums.ErrorCodeConstants.*;

/**
 * 字典 Service 实现类
 *
 * @author 芋道源码
 */
@Service
@Validated
public class CodeServiceImpl implements CodeService {

    @Resource
    private CodeMapper codeMapper;

    @Override
    public Integer createCode(CodeSaveReqVO createReqVO) {
        // 插入
        CodeDO code = BeanUtils.toBean(createReqVO, CodeDO.class);
        codeMapper.insert(code);
        // 返回
        return code.getId();
    }

    @Override
    public void updateCode(CodeSaveReqVO updateReqVO) {
        // 校验存在
        validateCodeExists(updateReqVO.getId());
        // 更新
        CodeDO updateObj = BeanUtils.toBean(updateReqVO, CodeDO.class);
        codeMapper.updateById(updateObj);
    }

    @Override
    public void deleteCode(Integer id) {
        // 校验存在
        validateCodeExists(id);
        // 删除
        codeMapper.deleteById(id);
    }

    private void validateCodeExists(Integer id) {
        if (codeMapper.selectById(id) == null) {
            throw exception(CODE_NOT_EXISTS);
        }
    }

    @Override
    public CodeDO getCode(Integer id) {
        return codeMapper.selectById(id);
    }

    @Override
    public PageResult<CodeDO> getCodePage(CodePageReqVO pageReqVO) {
        return codeMapper.selectPage(pageReqVO);
    }

    @Override
    public List<Tree<String>> getTree() {
        List<CodeDO> nodeList = codeMapper.selectList();

        //配置
        TreeNodeConfig treeNodeConfig = new TreeNodeConfig();
// 自定义属性名 都有默认值的
        treeNodeConfig.setWeightKey("order");
        treeNodeConfig.setIdKey("id");
// 最大递归深度
        treeNodeConfig.setDeep(3);

//转换器 (含义:找出父节点为字符串零的所有子节点, 并递归查找对应的子节点, 深度最多为 3)
        List<Tree<String>> treeNodes = TreeUtil.<CodeDO, String>build(nodeList, "0", treeNodeConfig,
                (treeNode, tree) -> {
                    tree.setId(String.valueOf(treeNode.getId()));
                    tree.setParentId(String.valueOf(treeNode.getPid()));

                    tree.setName(treeNode.getCodeTxt());
                    // 扩展属性 ...
                    tree.putExtra("codeId", treeNode.getCodeId());
                    tree.putExtra("label", treeNode.getCodeTxt());

                });
        treeNodes.forEach(tree -> {
            if (ObjectUtil.isEmpty(tree.getChildren())) {
                tree.setChildren(new ArrayList<>());
            }
        });
        return treeNodes;

    }

    @Override
    public String getCodeName(String projectCate) {
        if (ObjectUtil.isNotEmpty(projectCate)) {
            CodeDO codeDO = codeMapper.selectOne(CodeDO::getCodeId, projectCate);
            if (ObjectUtil.isNotEmpty(codeDO)) {
                return codeDO.getCodeTxt();
            }
        }
        return null;
    }

    @Override
    public CodeDO getCodeByName(String k) {
        LambdaQueryWrapper<CodeDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CodeDO::getCodeTxt,k);
        return codeMapper.selectOne(queryWrapper);
    }
}